﻿using System;
using System.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x020000DB RID: 219
	internal sealed class TypeReferenceEqualityComparer : EqualityComparer<TypeReference>
	{
		// Token: 0x060008EA RID: 2282 RVA: 0x00026308 File Offset: 0x00024508
		public override bool Equals(TypeReference x, TypeReference y)
		{
			return TypeReferenceEqualityComparer.AreEqual(x, y, TypeComparisonMode.Exact);
		}

		// Token: 0x060008EB RID: 2283 RVA: 0x00026324 File Offset: 0x00024524
		public override int GetHashCode(TypeReference obj)
		{
			return TypeReferenceEqualityComparer.GetHashCodeFor(obj);
		}

		// Token: 0x060008EC RID: 2284 RVA: 0x0002633C File Offset: 0x0002453C
		public static bool AreEqual(TypeReference a, TypeReference b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact)
		{
			bool flag = a == b;
			bool result;
			if (flag)
			{
				result = true;
			}
			else
			{
				bool flag2 = a == null || b == null;
				if (flag2)
				{
					result = false;
				}
				else
				{
					MetadataType metadataType = a.MetadataType;
					MetadataType metadataType2 = b.MetadataType;
					bool flag3 = metadataType == MetadataType.GenericInstance || metadataType2 == MetadataType.GenericInstance;
					if (flag3)
					{
						bool flag4 = metadataType != metadataType2;
						result = (!flag4 && TypeReferenceEqualityComparer.AreEqual((GenericInstanceType)a, (GenericInstanceType)b, comparisonMode));
					}
					else
					{
						bool flag5 = metadataType == MetadataType.Array || metadataType2 == MetadataType.Array;
						if (flag5)
						{
							bool flag6 = metadataType != metadataType2;
							if (flag6)
							{
								result = false;
							}
							else
							{
								ArrayType arrayType = (ArrayType)a;
								ArrayType arrayType2 = (ArrayType)b;
								bool flag7 = arrayType.Rank != arrayType2.Rank;
								result = (!flag7 && TypeReferenceEqualityComparer.AreEqual(arrayType.ElementType, arrayType2.ElementType, comparisonMode));
							}
						}
						else
						{
							bool flag8 = metadataType == MetadataType.Var || metadataType2 == MetadataType.Var;
							if (flag8)
							{
								bool flag9 = metadataType != metadataType2;
								result = (!flag9 && TypeReferenceEqualityComparer.AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode));
							}
							else
							{
								bool flag10 = metadataType == MetadataType.MVar || metadataType2 == MetadataType.MVar;
								if (flag10)
								{
									bool flag11 = metadataType != metadataType2;
									result = (!flag11 && TypeReferenceEqualityComparer.AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode));
								}
								else
								{
									bool flag12 = metadataType == MetadataType.ByReference || metadataType2 == MetadataType.ByReference;
									if (flag12)
									{
										bool flag13 = metadataType != metadataType2;
										result = (!flag13 && TypeReferenceEqualityComparer.AreEqual(((ByReferenceType)a).ElementType, ((ByReferenceType)b).ElementType, comparisonMode));
									}
									else
									{
										bool flag14 = metadataType == MetadataType.Pointer || metadataType2 == MetadataType.Pointer;
										if (flag14)
										{
											bool flag15 = metadataType != metadataType2;
											result = (!flag15 && TypeReferenceEqualityComparer.AreEqual(((PointerType)a).ElementType, ((PointerType)b).ElementType, comparisonMode));
										}
										else
										{
											bool flag16 = metadataType == MetadataType.RequiredModifier || metadataType2 == MetadataType.RequiredModifier;
											if (flag16)
											{
												bool flag17 = metadataType != metadataType2;
												if (flag17)
												{
													result = false;
												}
												else
												{
													RequiredModifierType requiredModifierType = (RequiredModifierType)a;
													RequiredModifierType requiredModifierType2 = (RequiredModifierType)b;
													result = (TypeReferenceEqualityComparer.AreEqual(requiredModifierType.ModifierType, requiredModifierType2.ModifierType, comparisonMode) && TypeReferenceEqualityComparer.AreEqual(requiredModifierType.ElementType, requiredModifierType2.ElementType, comparisonMode));
												}
											}
											else
											{
												bool flag18 = metadataType == MetadataType.OptionalModifier || metadataType2 == MetadataType.OptionalModifier;
												if (flag18)
												{
													bool flag19 = metadataType != metadataType2;
													if (flag19)
													{
														result = false;
													}
													else
													{
														OptionalModifierType optionalModifierType = (OptionalModifierType)a;
														OptionalModifierType optionalModifierType2 = (OptionalModifierType)b;
														result = (TypeReferenceEqualityComparer.AreEqual(optionalModifierType.ModifierType, optionalModifierType2.ModifierType, comparisonMode) && TypeReferenceEqualityComparer.AreEqual(optionalModifierType.ElementType, optionalModifierType2.ElementType, comparisonMode));
													}
												}
												else
												{
													bool flag20 = metadataType == MetadataType.Pinned || metadataType2 == MetadataType.Pinned;
													if (flag20)
													{
														bool flag21 = metadataType != metadataType2;
														result = (!flag21 && TypeReferenceEqualityComparer.AreEqual(((PinnedType)a).ElementType, ((PinnedType)b).ElementType, comparisonMode));
													}
													else
													{
														bool flag22 = metadataType == MetadataType.Sentinel || metadataType2 == MetadataType.Sentinel;
														if (flag22)
														{
															bool flag23 = metadataType != metadataType2;
															result = (!flag23 && TypeReferenceEqualityComparer.AreEqual(((SentinelType)a).ElementType, ((SentinelType)b).ElementType, comparisonMode));
														}
														else
														{
															bool flag24 = !a.Name.Equals(b.Name) || !a.Namespace.Equals(b.Namespace);
															if (flag24)
															{
																result = false;
															}
															else
															{
																TypeDefinition typeDefinition = a.Resolve();
																TypeDefinition typeDefinition2 = b.Resolve();
																bool flag25 = comparisonMode == TypeComparisonMode.SignatureOnlyLoose;
																if (flag25)
																{
																	bool flag26 = typeDefinition.Module.Name != typeDefinition2.Module.Name;
																	if (flag26)
																	{
																		result = false;
																	}
																	else
																	{
																		bool flag27 = typeDefinition.Module.Assembly.Name.Name != typeDefinition2.Module.Assembly.Name.Name;
																		result = (!flag27 && typeDefinition.FullName == typeDefinition2.FullName);
																	}
																}
																else
																{
																	result = (typeDefinition == typeDefinition2);
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		// Token: 0x060008ED RID: 2285 RVA: 0x00026798 File Offset: 0x00024998
		private static bool AreEqual(GenericParameter a, GenericParameter b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact)
		{
			bool flag = a == b;
			bool result;
			if (flag)
			{
				result = true;
			}
			else
			{
				bool flag2 = a.Position != b.Position;
				if (flag2)
				{
					result = false;
				}
				else
				{
					bool flag3 = a.Type != b.Type;
					if (flag3)
					{
						result = false;
					}
					else
					{
						TypeReference typeReference = a.Owner as TypeReference;
						bool flag4 = typeReference != null && TypeReferenceEqualityComparer.AreEqual(typeReference, b.Owner as TypeReference, comparisonMode);
						if (flag4)
						{
							result = true;
						}
						else
						{
							MethodReference methodReference = a.Owner as MethodReference;
							bool flag5 = methodReference != null && comparisonMode != TypeComparisonMode.SignatureOnlyLoose && MethodReferenceComparer.AreEqual(methodReference, b.Owner as MethodReference);
							result = (flag5 || comparisonMode == TypeComparisonMode.SignatureOnly || comparisonMode == TypeComparisonMode.SignatureOnlyLoose);
						}
					}
				}
			}
			return result;
		}

		// Token: 0x060008EE RID: 2286 RVA: 0x0002685C File Offset: 0x00024A5C
		private static bool AreEqual(GenericInstanceType a, GenericInstanceType b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact)
		{
			bool flag = a == b;
			bool result;
			if (flag)
			{
				result = true;
			}
			else
			{
				int count = a.GenericArguments.Count;
				bool flag2 = count != b.GenericArguments.Count;
				if (flag2)
				{
					result = false;
				}
				else
				{
					bool flag3 = !TypeReferenceEqualityComparer.AreEqual(a.ElementType, b.ElementType, comparisonMode);
					if (flag3)
					{
						result = false;
					}
					else
					{
						for (int i = 0; i < count; i++)
						{
							bool flag4 = !TypeReferenceEqualityComparer.AreEqual(a.GenericArguments[i], b.GenericArguments[i], comparisonMode);
							if (flag4)
							{
								return false;
							}
						}
						result = true;
					}
				}
			}
			return result;
		}

		// Token: 0x060008EF RID: 2287 RVA: 0x00026908 File Offset: 0x00024B08
		public static int GetHashCodeFor(TypeReference obj)
		{
			MetadataType metadataType = obj.MetadataType;
			bool flag = metadataType == MetadataType.GenericInstance;
			int result;
			if (flag)
			{
				GenericInstanceType genericInstanceType = (GenericInstanceType)obj;
				int num = TypeReferenceEqualityComparer.GetHashCodeFor(genericInstanceType.ElementType) * 486187739 + 31;
				for (int i = 0; i < genericInstanceType.GenericArguments.Count; i++)
				{
					num = num * 486187739 + TypeReferenceEqualityComparer.GetHashCodeFor(genericInstanceType.GenericArguments[i]);
				}
				result = num;
			}
			else
			{
				bool flag2 = metadataType == MetadataType.Array;
				if (flag2)
				{
					ArrayType arrayType = (ArrayType)obj;
					result = TypeReferenceEqualityComparer.GetHashCodeFor(arrayType.ElementType) * 486187739 + arrayType.Rank.GetHashCode();
				}
				else
				{
					bool flag3 = metadataType == MetadataType.Var || metadataType == MetadataType.MVar;
					if (flag3)
					{
						GenericParameter genericParameter = (GenericParameter)obj;
						int num2 = genericParameter.Position.GetHashCode() * 486187739;
						int num3 = (int)metadataType;
						int num4 = num2 + num3.GetHashCode();
						TypeReference typeReference = genericParameter.Owner as TypeReference;
						bool flag4 = typeReference != null;
						if (flag4)
						{
							result = num4 * 486187739 + TypeReferenceEqualityComparer.GetHashCodeFor(typeReference);
						}
						else
						{
							MethodReference methodReference = genericParameter.Owner as MethodReference;
							bool flag5 = methodReference != null;
							if (!flag5)
							{
								throw new InvalidOperationException("Generic parameter encountered with invalid owner");
							}
							result = num4 * 486187739 + MethodReferenceComparer.GetHashCodeFor(methodReference);
						}
					}
					else
					{
						bool flag6 = metadataType == MetadataType.ByReference;
						if (flag6)
						{
							ByReferenceType byReferenceType = (ByReferenceType)obj;
							result = TypeReferenceEqualityComparer.GetHashCodeFor(byReferenceType.ElementType) * 486187739 * 37;
						}
						else
						{
							bool flag7 = metadataType == MetadataType.Pointer;
							if (flag7)
							{
								PointerType pointerType = (PointerType)obj;
								result = TypeReferenceEqualityComparer.GetHashCodeFor(pointerType.ElementType) * 486187739 * 41;
							}
							else
							{
								bool flag8 = metadataType == MetadataType.RequiredModifier;
								if (flag8)
								{
									RequiredModifierType requiredModifierType = (RequiredModifierType)obj;
									int num5 = TypeReferenceEqualityComparer.GetHashCodeFor(requiredModifierType.ElementType) * 43;
									num5 = num5 * 486187739 + TypeReferenceEqualityComparer.GetHashCodeFor(requiredModifierType.ModifierType);
									result = num5;
								}
								else
								{
									bool flag9 = metadataType == MetadataType.OptionalModifier;
									if (flag9)
									{
										OptionalModifierType optionalModifierType = (OptionalModifierType)obj;
										int num6 = TypeReferenceEqualityComparer.GetHashCodeFor(optionalModifierType.ElementType) * 47;
										num6 = num6 * 486187739 + TypeReferenceEqualityComparer.GetHashCodeFor(optionalModifierType.ModifierType);
										result = num6;
									}
									else
									{
										bool flag10 = metadataType == MetadataType.Pinned;
										if (flag10)
										{
											PinnedType pinnedType = (PinnedType)obj;
											result = TypeReferenceEqualityComparer.GetHashCodeFor(pinnedType.ElementType) * 486187739 * 53;
										}
										else
										{
											bool flag11 = metadataType == MetadataType.Sentinel;
											if (flag11)
											{
												SentinelType sentinelType = (SentinelType)obj;
												result = TypeReferenceEqualityComparer.GetHashCodeFor(sentinelType.ElementType) * 486187739 * 59;
											}
											else
											{
												bool flag12 = metadataType == MetadataType.FunctionPointer;
												if (flag12)
												{
													throw new NotImplementedException("We currently don't handle function pointer types.");
												}
												result = obj.Namespace.GetHashCode() * 486187739 + obj.FullName.GetHashCode();
											}
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}
	}
}
